﻿using System;
using System.Windows;
using System.Windows.Controls.Primitives;

namespace Com.Lancetinc.Evs.Controls;

public class LevsUniformGrid : UniformGrid
{
    public static readonly DependencyProperty ColumnSpacingProperty = DependencyProperty.RegisterAttached(
    nameof(ColumnSpacing), typeof(double), typeof(LevsUniformGrid),
    new FrameworkPropertyMetadata(0D, FrameworkPropertyMetadataOptions.AffectsMeasure));
    public double ColumnSpacing
    {
        get => (double)GetValue(ColumnSpacingProperty);
        set => SetValue(ColumnSpacingProperty, value);
    }

    public static readonly DependencyProperty RowSpacingProperty = DependencyProperty.RegisterAttached(
        nameof(RowSpacing), typeof(double), typeof(LevsUniformGrid),
        new FrameworkPropertyMetadata(0D, FrameworkPropertyMetadataOptions.AffectsMeasure));
    public double RowSpacing
    {
        get => (double)GetValue(RowSpacingProperty);
        set => SetValue(RowSpacingProperty, value);
    }

    /// <inheritdoc />
    protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)
    {
        base.OnVisualChildrenChanged(visualAdded, visualRemoved);
        ResetMargin();
    }

    /// <inheritdoc />
    protected override Size MeasureOverride(Size constraint)
    {
        // OnVisualChildrenChanged被调用的时候，Children.Count是删除前的数量,并不准确，因此在MeasureOverride的时候也更新一次
        if (_prevChildrenCount > -1 && _prevChildrenCount != Children.Count)
        {
            ResetMargin();
        }

        return base.MeasureOverride(constraint);
    }

    private int _prevChildrenCount = -1;
    private void ResetMargin()
    {
        if (this.Children.Count == 0)
            return;

        _prevChildrenCount = Children.Count;

        if (ColumnSpacing == 0 && RowSpacing == 0)
            return;

        var colCount = Columns;
        var rowCount = (int)Math.Ceiling(Children.Count * 1.0 / colCount);
        var halfColumnSpacing = ColumnSpacing / 2;
        var halfRowSpacing = RowSpacing / 2;

        for (int i = 0; i < Children.Count; i++)
        {
            var child = Children[i] as FrameworkElement;
            if (child == null) continue;

            double left, top, right, bottom;

            left = right = halfColumnSpacing;
            top = bottom = halfRowSpacing;

            var c = i % colCount;
            var r = i / colCount;
            if (c == 0)
                left = 0;
            if (r == 0)
                top = 0;
            if (c == colCount - 1)
                right = 0;
            if (r == rowCount - 1)
                bottom = 0;

            child.Margin = new Thickness(left, top, right, bottom);
        }
    }
}